/*********************************************************
 * 初学之家(http://www.g2room.com)，提供Java、Javascript（js）、Jquery、
 * 等一些工具或常用功能的实现例子代码，希望能给初学者提供学习和工作上的帮助，
 * 也希望有想提供源代码的朋友能联系我，一起努力，提供更多、更全面、更详细的
 * 一些初学代码例子及经验，帮助更多的人。
 * 
 * 我的联系方式：E-Mail：g2room@163.com
 * 网址：http://www.g2room.com
 * QQ：天涯（1173930590）
 * QQ交流群：323642758
 * 
 * 本站内容为提供各种java、javascript(JS)常用的工具源代码、实例（示例）、
 * 基本配置、教程、手册等；目前Java代码提供的工具（或转换）例子代码如下：
 * BASE64转换工具、bytes相关操作、email收发、文件操作（读写、拷贝、遍历、
 * 多线程copy等）、json格式转换、日志（Log4j）操作工具、Lucene搜索引擎的
 * 创建索引和搜索、各种不同Map的使用、定时器（Quartz）的使用例子、Socket的
 * 连接传输数据例子、WebService的例子及一些常用的工具类如String、Date及
 * JDK自带的一些工具类及函数的使用例子。
 * 
 * 说明：如需直接使用本站的例子代码，请保留此说明
 * 
 ********************************************************/
package com.g2room.security;

import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.Security;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.KeyGenerator;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;

/**
 * 
 *
 * @createTime: Jul 8, 2013 3:44:35 PM
 * @author: <a href="mailto:g2room@163.com">天涯</a>
 * @version: 0.1
 * @lastVersion: 0.1
 * @updateTime: 
 * @updateAuthor: <a href="mailto:g2room@163.com">天涯</a>
 * @changesSum: 
 * 
 */
public class ThreeDES {
	//定义 加密算法,可用：
	//“Blowfish”、“DES”、“DESede”、“HmacMD5”或“HmacSHA1”
	private static final String Algorithm = "DES";
    
	/**
	 * 获取密钥
	 *
	 * @return
	 * @throws NoSuchAlgorithmException
	 * @auther <a href="mailto:g2room@163.com">天涯</a>
	 * Jul 8, 2013 3:53:10 PM
	 */
	private static byte[] getKey() throws NoSuchAlgorithmException {
		// 获取密钥生成器
 	   KeyGenerator kg = KeyGenerator.getInstance(Algorithm);
 	   /**
 	   	指定密钥的长度。如果该步骤省略的话，会根据算法自动使用默
 	   	认的密钥长度。指定长度时，若第一步密钥生成器使用的是“DES”算法，则密钥长度
 	   	必须是56 位；若是“DESede”，则可以是112 或168 位，其中112 位有效；若是“AES”，
 	   	可以是128, 192 或256 位；若是“Blowfish”，则可以是32 至448 之间可以被8 整除
 	   	的数；“HmacMD5”和“HmacSHA1”默认的密钥长度都是64 个字节。
 	   */
 	   kg.init(56);
 	   // 密钥的字节方式
 	   SecretKey key = kg.generateKey();
 	   return key.getEncoded();
	}
	
	/**
	 * 
	 * 加密
	 *
	 * @param text 需要加密的文本
	 * @param key	密钥
	 *
	 * @return 加密后的byte数组
	 * @throws NoSuchAlgorithmException
	 * @throws NoSuchPaddingException
	 * @throws InvalidKeyException
	 * @throws UnsupportedEncodingException
	 * @throws IllegalBlockSizeException
	 * @throws BadPaddingException
	 * @auther <a href="mailto:g2room@163.com">天涯</a>
	 * Jul 8, 2013 4:02:30 PM
	 */
	public static byte[] encrypt(String text, byte[] key) throws NoSuchAlgorithmException,
			NoSuchPaddingException, InvalidKeyException,
			UnsupportedEncodingException, IllegalBlockSizeException,
			BadPaddingException {
		 // 创建密码器（Cipher对象）
		 Cipher cp = Cipher.getInstance(Algorithm);
		//生成密钥
         SecretKey deskey = new SecretKeySpec(key, Algorithm);
		 // 初始化密码器
		 cp.init(Cipher.ENCRYPT_MODE, deskey);
		 // 获取等待加密的明文
		 byte ptext[] = text.getBytes("UTF8");
		// 执行加密
		return cp.doFinal(ptext);
	}
	
	/**
	 * 解密
	 *
	 * @param ciphertext	解密的内容
	 * @param key	密钥
	 * @return
	 * @throws NoSuchAlgorithmException
	 * @throws NoSuchPaddingException
	 * @throws InvalidKeyException
	 * @throws IllegalBlockSizeException
	 * @throws BadPaddingException
	 * @auther <a href="mailto:g2room@163.com">天涯</a>
	 * Jul 8, 2013 4:14:53 PM
	 */
	public static byte[] decrypt(byte[] ciphertext, byte[] key) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
		// 获取密钥
		SecretKeySpec deskey = new SecretKeySpec(key, Algorithm);
		// 创建密码器（Cipher 对象）
		Cipher cp = Cipher.getInstance(Algorithm);
		// 初始化密码器
		cp.init(Cipher.DECRYPT_MODE, deskey);
		// 执行解密
		return cp.doFinal(ciphertext);
	}

    //转换成十六进制字符串
    public static String byte2hex(byte[] b) {
        String hs="";
        String stmp="";

        for (int n=0;n<b.length;n++) {
            stmp=(java.lang.Integer.toHexString(b[n] & 0XFF));
            if (stmp.length()==1) hs=hs+"0"+stmp;
            else hs=hs+stmp;
            if (n<b.length-1)  hs=hs+":";
        }
        return hs.toUpperCase();
    }
    
    public static void main(String[] args)
    {
        //添加新安全算法,如果用JCE就要把它添加进去
        Security.addProvider(new com.sun.crypto.provider.SunJCE());

        String szSrc = "This is a 3DES test. 测试";
        
        System.out.println("加密前的字符串:" + szSrc);
        
		try {
			final byte[] key = getKey();    //24字节的密钥
			byte[] encoded = encrypt(szSrc, key);
			System.out.println("加密后的字符串:" + new String(encoded, "utf-8"));

	        
	        byte[] srcBytes = decrypt(encoded, key);
	        System.out.println("解密后的字符串:" + (new String(srcBytes, "utf-8")));
		} catch (InvalidKeyException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (NoSuchAlgorithmException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (NoSuchPaddingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (UnsupportedEncodingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalBlockSizeException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (BadPaddingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}        
    }
}
